package com.lock.reentrantLock;

import java.util.Random;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @PackageName:com.lock.reentrantLock
 * @ClassName:Test08
 * @Description: 使用tryLock()可以避免死锁
 * @Author: zhangxiaoyu
 * @date 2021/1/20 13:52
 */
public class Test08 {

    static class IntLock implements Runnable {

        private static ReentrantLock lock1 = new ReentrantLock();
        private static ReentrantLock lock2 = new ReentrantLock();

        private int lockNum;

        public IntLock(int lockNum) {
            this.lockNum = lockNum;
        }

        @Override
        public void run() {

            if (lockNum % 2 == 0) {  //偶数先锁1，再锁2

                while (true) {
                    try {
                        if (lock1.tryLock()) {
                            System.out.println(Thread.currentThread().getName() + "获得锁1，还想获得锁2");
                            Thread.sleep(new Random().nextInt(1000));
                        }
                        try {
                            if (lock2.tryLock()) {
                                System.out.println(Thread.currentThread().getName() + "同时获得锁1和锁2 -----完成任务");
                                Thread.sleep(new Random().nextInt(1000));
                                return;  //结束run，当前线程结束
                            }
                        } finally {

                            if (lock2.isHeldByCurrentThread()) {
                                lock2.unlock();
                            }
                        }

                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {

                        if (lock1.isHeldByCurrentThread()) {
                            lock1.unlock();
                        }
                    }
                }

            } else {

                while (true) {
                    try {
                        if (lock2.tryLock()) {
                            System.out.println(Thread.currentThread().getName() + "获得锁2，还想获得锁1");
                            Thread.sleep(100);
                        }
                        try {
                            if (lock1.tryLock()) {
                                System.out.println(Thread.currentThread().getName() + "同时获得锁2和锁1 -----完成任务");
                                Thread.sleep(100);
                                return;  //结束run，当前线程结束
                            }
                        } finally {

                            if (lock1.isHeldByCurrentThread()) {
                                lock1.unlock();
                            }
                        }

                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {

                        if (lock2.isHeldByCurrentThread()) {
                            lock2.unlock();
                        }
                    }
                }


            }

        }
    }

    public static void main(String[] args) {
        IntLock intLock1 = new IntLock(11);
        IntLock intLock2 = new IntLock(22);

        Thread t1 = new Thread(intLock1);
        Thread t2 = new Thread(intLock2);

        t1.start();
        t2.start();

        //运行后，使用tryLock尝试获得锁，不会等待，而是通过循环不停的尝试，如果等待的时间足够长，线程总是会获得想要的资源

    }
}
